#include "comm.hpp"

// 需求：创建进程池(N)，随机执行进程及任务(可指定)，交给服务端处理

// 单个进程成员类
class ProcMember
{
public:
    ProcMember(pid_t pid = pid_t(), int fd = int())
        : _child_pid(pid), _write_fd(fd)
    {
        char nameBuffer[64]; // 缓冲区
        snprintf(nameBuffer, sizeof nameBuffer, "Process %d [%d:%d]", num++, _child_pid, _write_fd);
        processName = string(nameBuffer, nameBuffer + sizeof nameBuffer);
    }

    const string &name() const
    {
        return processName;
    }

    pid_t _child_pid;
    int _write_fd;
    string processName;
    static int num;
};

int ProcMember::num = 0;

class Process
{
public:
    Process()
    {
        createProcess();
    }

    ~Process()
    {
        waitChild();
    }

    // void waitcommand()
    // {
    //     while (true)
    //     {
    //         // 选择进程及任务
    //         srand((size_t)time(NULL));

    //         int index = 0;
    //         sleep(1);
    //         cout << "请选择进程:>";
    //         cin >> index;

    //         cout << proc_task_pool[index].name() << endl;

    //         if (index < 0 || index >= proc_num)
    //         {
    //             cout << "进程选择错误！" << endl;
    //             continue;
    //         }

    //         int task = showBoard();
    //         // cout << "index: " << index << " | "
    //         //      << "task: " << task << endl;

    //         if (task == 3)
    //             break;
    //         else
    //         {
    //             write(proc_task_pool[index]._write_fd, &task, sizeof task);
    //             //cerr << "proc_task_pool[index]._write_fd: " << proc_task_pool[index]._write_fd << endl;
    //             cout << "success!" << endl;
    //         }
    //         sleep(1);
    //     }
    // }

    void waitCommand(int wfd)
    {
        while (true)
        {
            cout << "子进程 " << getpid() << " 已准备就绪！" << endl;
            int command = 0;
            int n = read(0, &command, sizeof command);

            if (n == sizeof command)
                write(wfd, &command, sizeof command);
            else
            {
                cout << "子进程执行任务失败，已退出！ PID: " << getpid() << endl;
                break;
            }
        }
    }

    void createProcess()
    {
        vector<int> fds;
        for (int i = 0; i < proc_num; i++)
        {
            pid_t id = fork(); // 创建子进程

            // cerr << "Test i: " << i << " vf[i].c_str(): " << vf[i].c_str() << endl;
            int wfd = open(vf[i].c_str(), O_WRONLY);
            assert(wfd != -1);
            (void)wfd;
            cout << "wfd " << wfd << endl;

            if (id == 0)
            {
                for (auto &e : fds)
                    cerr << "fds:" << e << endl, close(e);

                // // Test
                // cout << i << " | "
                //      << "pid " << getpid() << " | "
                //                               "ppid "
                //      << getppid() << endl;

                waitCommand(wfd);
            }

            proc_task_pool.push_back(ProcMember(id, wfd));
            fds.push_back(wfd);
        }
    }

    int showBoard()
    {
        sleep(1);
        cout << "**************************" << endl;
        cout << "* 0.日志打印  1.数据插入 *" << endl;
        cout << "* 2.网络请求  3.退出程序 *" << endl;
        cout << "**************************" << endl;
        cout << "请选择:)";
        int task = 0;
        cin >> task;
        return task;
    }

    void chooseTask()
    {
        // 选择进程及任务
        srand((size_t)time(NULL));

        int index = rand() % proc_num;
        cout << "已选择 " << index << " 号进程" << endl;

        int task = showBoard();
        write(proc_task_pool[index]._write_fd, &task, sizeof task);
    }

    void waitChild()
    {
        for (auto e : proc_task_pool)
            close(e._write_fd); // 关闭写端 fd
        cout << "写端fd 已关闭" << endl;

        for (auto e : proc_task_pool)
            waitpid(e._child_pid, NULL, 0);
        cout << "子进程 已等待" << endl;
    }

private:
    vector<ProcMember> proc_task_pool; // 进程池
    const int proc_num = 3;            // 进程数
};

int main()
{
    int a = 0;
    Process p1;
    // p1.chooseTask();
    // p1.waitcommand();
    return 0;
}